package us.mooresr.aircraftscheduling.server.handler;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import us.mooresr.aircraftscheduling.server.BCrypt;
import us.mooresr.aircraftscheduling.server.DAO;
import us.mooresr.aircraftscheduling.shared.action.CreateUserAction;
import us.mooresr.aircraftscheduling.shared.action.LoginAction;
import us.mooresr.aircraftscheduling.shared.action.LoginResult;
import us.mooresr.aircraftscheduling.shared.model.User;
import us.mooresr.aircraftscheduling.shared.model.UserDetail;

import com.gwtplatform.dispatch.server.actionhandler.ActionHandler;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.googlecode.objectify.Query;
import com.gwtplatform.dispatch.server.ExecutionContext;
import com.gwtplatform.dispatch.shared.ActionException;

public class LoginHandler implements
		ActionHandler<LoginAction, LoginResult> {
	
	private final Provider<HttpServletRequest> requestProvider;

	@Inject
	public LoginHandler(final Provider<HttpServletRequest> requestProvider) {
		this.requestProvider = requestProvider;
	}

	@Override
	public LoginResult execute(LoginAction action, ExecutionContext context)
			throws ActionException {
		LoginResult result;
		DAO dao = new DAO();
		
		// Special case - check for an empty user file.  If there are no users at all then we'll
		// initialize the datastore with a single Admin user first
		
		if (dao.ofy().query(User.class).count() == 0) {
			User newUser = new User(null, "Admin User", false);
			UserDetail newUserDetail = new UserDetail(null, "admin", "admin", null, null, null,
					null, null, null, null, null, null, true, true, true);
			CreateUserAction newAction = new CreateUserAction(newUser, newUserDetail);
			
			CreateUserActionHandler handler = new CreateUserActionHandler();
			handler.execute(newAction, context);
		}
		
		User user = null;
		UserDetail userDetail = dao.ofy().query(UserDetail.class).filter("username", action.getUser()).get();
		if (userDetail != null) {
			user = dao.ofy().get(User.class, userDetail.getId());
		}
		
		if (userDetail == null) {
			// Username not found
			result = new LoginResult(null);
		} else {
			if (BCrypt.checkpw(action.getPassword(), userDetail.getHashedPassword())) {
				// Success
				userDetail.setName(user.getName());
				result = new LoginResult(userDetail);
			} else {
				// Password mismatch
				result = new LoginResult(null);
			}
			
			if (user.getIsInactive()) {
				// Fail logins for inactive users
				result = new LoginResult(null);
			}
			
		}
		
		return result;
		
		/*
		// Test Code.  If the username and password match return "1234", else return "null"
		if (action.getUser().equals(action.getPassword())) {
			result = new LoginResult((long)1234);
			HttpSession session = requestProvider.get().getSession();
			session.setAttribute("login.authenticated", result.getUserId());
			return result;
		} else {
			return new LoginResult(null);
		}
		*/
		
	}

	@Override
	public void undo(LoginAction action, LoginResult result,
			ExecutionContext context) throws ActionException {
	}

	@Override
	public Class<LoginAction> getActionType() {
		return LoginAction.class;
	}
}
